/**
  *@description:中信银行借记卡，抓取流程包装处理
  *@author: LiTao
  *@date:2018/8/14
 */

/**
 * @description:中信借记卡抓取、解析主流程
 */
function debit_crawl_main(){
    //解析首页，获取部分数据,填充到上下文
    citic_debit_handle.parseIndex();

    //根据上下文的卡数量，初始化对应的封装对象，供全局使用
    createData();

    //从上下文获取账号集合
    var accountNoList = context.get(keys.USER_ACCOUNTNO);

    //遍历每张卡
    for(var cardIndex=0;cardIndex<accountNoList.size();cardIndex++){

        var accountNo=accountNoList.get(cardIndex);

        //从上下文，获取数据对象集合
        var data_list = context.get(ALL_DATA);
        var debitCardAllData=data_list.get(cardIndex);

        //抓取卡列表，获取账户的基础信息页面
        var cardHtml=citic_debit_handle.crawlCardInfo(cardIndex,accountNo);

        //解析卡列表，填充账户的基础信息
        citic_debit_handle.parseCardInfo(accountNo,cardHtml,debitCardAllData);

        //抓取已出账单
        var billEveryMonthList=citic_debit_handle.crawlDONE(cardIndex,accountNo);

        //解析已出账单
        citic_debit_handle.parseDONE(accountNo,billEveryMonthList,debitCardAllData);
        logger.info("debitCardAllData==="+debitCardAllData);
    }

}


/*********************************封装不同业务数据的抓取、解析****************************************/
var citic_debit_handle={
    /**
     * @scription:解析首页，获取部分数据
     */
    parseIndex:function(){
        //从上下文获取首页
        var indexPage=context.get(keys.INDEX_PAGE);

        //解析首页，获取EMP_SID信息
        var  EMP_SID=parseEMP_SID(indexPage);

        // 这里使用解析页面的方法取出卡号
        var doc = Jsoup.parse(indexPage);
        var name = doc.select("[class=userName]").text();
        context.put("cardname",name);
        var elements=doc.select(".newCardFontRed");
        //存放账号
        var accountNoList=new ArrayList();

        for each( var element in elements){
            if(element!=null&&element.text()!=""){
                if(element.text().contains("借记卡")){
                    accountNo=element.child(0).attr("id").replace("level","");
                    accountNoList.add(accountNo) ;
                }
            }
        }

        if(accountNoList.size()==0){
            throw new BankException("未获取到卡片信息，请登录官网绑定卡片");
        }

        //添加到上下文
        context.put(keys.USER_ACCOUNTNO,accountNoList) ;

        //"debitCardSize",在createData()中使用，用于创建对应数量的卡对象
        context.put("debitCardSize",accountNoList.size());

        context.put(keys.EMP_SID, EMP_SID) ;
        return;


        //解析首页，获取EMP_SID信息
        function parseEMP_SID(indexPage){
            //EMP_SID的正则
            var express1 = "EMP_SID=[A-Z]{0,50}";
            var EMP_SID = null ;
            var matcher = getGroup0(express1,indexPage);
            //非空
            if (matcher!=undefined&&!"".equals(matcher)) {
                EMP_SID = matcher.replaceAll("EMP_SID=", "");
                logger.info("EMP_SID="+EMP_SID);
            }
            return EMP_SID;

        }
    },


    /**
     * @description:抓取卡列表，获取账户的基础信息页面
     */
    crawlCardInfo:function(cardIndex,accountNo){
        // 访问账户信息页面
        var html = getAccuountInfoForThreeTimes(cardIndex,accountNo);
        if(html.contains("WRONGACCOUNT")){
            throw new BankException(BankConstants.BACR_21301_10, "账户信息获取失败");
        }
        return html;

        //访问账户信息页面
        function getAccuountInfoForThreeTimes(cardIndex,accountNo) {
            var EMP_SID = context.get(keys.EMP_SID);

            //重试三次
            for(var i =0;i<2;i++){
                logger.info("开始访问账户信息页面");
                var html = ajax_get(
                    "https://i.bank.ecitic.com/perbank6/pb1110_query_detail.do?EMP_SID=" + EMP_SID + "&accountNo=" + accountNo + "&index=0ff0");
                storeDataToFile(context,html, cardIndex+"_card.txt");
                if(html.contains("获取")&& html.contains("失败")){
                    logger.info("中信借记卡获取信息失败，继续请求账户页面")
                    Thread.sleep(1500)
                }else {
                    return html
                }
            }
            if(i >= 2){
                return "WRONGACCOUNT";
            }
        }
    },

    /**
     * 抓取卡列表，填充账户的基础信息
     * @param cardAllData
     */
    parseCardInfo:function(accountNo,cardHtml,debitCardAllData){
        //解析账户信息
        getAccountInfo(cardHtml, debitCardAllData,accountNo);
    },

    /**
     * 抓取已出账单
     */
    crawlDONE:function(cardIndex,accountNo){

        //从上下文获取EMP_SID
        var EMP_SID = context.get(keys.EMP_SID);

        var paramHtml = ajax_get(
            "https://i.bank.ecitic.com/perbank6/trans_3063s.do?EMP_SID=" + EMP_SID + "&accountNo=" + accountNo + "&selectSubAccount=null");
        storeDataToFile(context,paramHtml, "params"+accountNo+".txt");

        //根据卡账单页，抓取每月已出账单,获取每个卡的所有已出账单列表
        var billEveryMonthList=crawlDoneEveryMonthList(cardIndex,EMP_SID,accountNo,paramHtml);

        return billEveryMonthList;


        /**
         * 根据参数页，抓取每月已出账单（共12个月）,返回集合列表
         * @param EMP_SID   会话ID
         * @param accountNo 卡号
         * @param paramHtml 参数页面
         */
        function crawlDoneEveryMonthList(cardIndex,EMP_SID,accountNo,paramHtml){
            //起始月
            var fst = getFirstMonthFirstDay();

            //添加日期到上下文
            context.put(keys.ONE_YEAR_LIST,fst);

            //上个月
            var lst = getBeforMonthLast();
            //购物账单集合
            var shoppingList=new ArrayList();

            //抓取12个月的已出购物账单
            for(var i=0;i<12;i++){
                var beginDate = fst.get(i);
                var endDate = lst.get(i);
                //获取购物详情页
                var url = "https://i.bank.ecitic.com/perbank6/pb1310_account_detail.do?EMP_SID=" + EMP_SID + "&payAcctxt=" + accountNo + getParamterUrlInfo(paramHtml, accountNo, beginDate, endDate) ;
                var shoppingHtml = ajax_get(url);
                storeDataToFile(context,shoppingHtml, cardIndex+"_card_"+beginDate+".txt");
                logger.info("持久化" +cardIndex+"_card_"+beginDate+".txt" +"月份的流水");
                //添加购物账单
                shoppingList.add(shoppingHtml);
            }
            return shoppingList;
        }
    },


    /**
     * 解析已出账单
     */
    parseDONE:function(accountNo,billEveryMonthList,debitCardAllData){
            //获取每个卡对应的月账单集合
            var billList=debitCardAllData.getBills();

            //舍弃掉creditCardAllData初始时创建的对象内容
            billList.clear();

            //遍历每个月
            for(var j=0;j<billEveryMonthList.size();j++){

                //获取每个月的账单详情
                var billdetailHtml=billEveryMonthList.get(j);

                //从上下文获取已出账单时间
                var oneYear=context.get(keys.ONE_YEAR_LIST);
                //解析已出账单详情页面
                parseBillDetailInfo(accountNo,oneYear.get(j),billdetailHtml, billList);

            }
        return;


        //解析账单详情页，填充数据
        function parseBillDetailInfo(accountNo,beginDate,billdetailHtml, billList){
            var bill = new BillAllData() ;
            bill.setBankName("中信银行");
            var sb = new StringBuilder(beginDate);
            var billdate = sb.insert(4, "-").insert(7,"-").toString() ;
            bill.setBillDate(yyyy_MM_dd_PARSER.parse(billdate));
            bill.setBillMonth(billdate.substring(0, 7));
            bill.setBillId(UUID.randomUUID().toString());
            bill.setBillType("DONE");

            var expenses = getBillInfo(billdetailHtml, accountNo) ;
            //添加购物明细
            bill.setShoppingSheets(expenses) ;

            //添加每月账单
            billList.add(bill);
            // bill.setCashLimit(null);
            // bill.setCreditLimit(null);
            // bill.setInterest(null);
            // bill.setLastBalance(null);
            // bill.setLastPayment(null);
            // bill.setMinPayment(null);
            // bill.setNewBalance(null);
            // bill.setNewCharges(null);
            // bill.setUsdCashLimit(null);
            // bill.setUsdCreditLimit(null);
            // bill.setUsdInterest(null);
            // bill.setUsdLastBalance(null);
            // bill.setUsdLastPayment(null);
            // bill.setUsdMinPayment(null);
            // bill.setUsdNewBalance(null);
            // bill.setUsdNewCharges(null);
        }

    }
}







/***************************************辅助型业务变量和方法******************************************/

/**
 *
 * @param html 卡信息页面
 * @param data  卡对象
 * @param accountNo 卡号
 */
function getAccountInfo( html, data,  accountNo) {
    try {
        var creditCardTimeDeposits = new ArrayList();
        var doc = Jsoup.parse(html);
        var eles = doc.select(".card-panel");
        var balance = null ;
        for(var i=0;i<eles.size();i++){
            var creditCardTimeDeposit = new CreditCardTimeDeposit();
            creditCardTimeDeposit.setCurrencyType("CNY");
            creditCardTimeDeposit.setDepositType(doc.select("div.title").get(i).text().replaceAll("\u00A0", ""));
            creditCardTimeDeposit.setDepositDate(null);
            var balance=doc.select("div.value-div > span").get(i+1).text().replaceAll("元","");
            if(balance!=""&&balance!=null){
                creditCardTimeDeposit.setBalance(new BigDecimal(balance));
            }

            var interest=doc.select("div.value-div > span").get(i).text().replaceAll("%", "").replaceAll("\u00A0", "");
            if (!StringUtils.isEmpty(interest)) {
                creditCardTimeDeposit.setInterest(new BigDecimal(interest).divide(new BigDecimal("100")));
            }
            var openCardTime=doc.select(".data-item").get(1).child(1).text();
            if(openCardTime!=""){
                data.setOpenTime(yyyyMMdd_PARSER.parse(openCardTime));
            }
            creditCardTimeDeposits.add(creditCardTimeDeposit);
        }
        data.setDeposits(creditCardTimeDeposits);
        if(accountNo.length>5){
            data.setCardNum(accountNo.substring(accountNo.length-4,accountNo.length));
        }
        if(accountNo!=""&&accountNo!=null){
            accountNo=accountNo.replace(accountNo.substring(4,accountNo.length()-4),"********");
        }
        data.setFullCardNum(accountNo);
        data.setCardType("借记卡");
        data.setBankName("中信银行");
        data.setCardId(UUID.randomUUID().toString());
        data.setCashBalance(null);
        data.setCashLimit(null);
        data.setCreditLimit(null);
        balance = doc.select("[id=balance]").val().replaceAll(",", "") ;
        if(!StringUtils.isEmpty(balance)){
            data.setBalance(new BigDecimal(balance));
        }
        data.setNameOnCard(context.get("cardname"));
    } catch (e) {
        logger.error("中信储蓄卡账户信息页面解析异常", e);
    }
}



/**
 * 解析流水信息页面
 * @param html
 * @param accNo
 * @return
 */
function getBillInfo( html, accNo){
    var expenses = new ArrayList() ;
    try {
        accNo = accNo.substring(accNo.length-4,accNo.length) ;
        var i = 1 ;
        var  doc = Jsoup.parse(html);
        var elements=doc.select("table#resultTable1>tbody").first().select("tr");
        for each (var element in elements){

            //交易时间
            var transTime=element.select("td").get(0).text();
            //收入金额 (拼接负号)
            var madeMoney=element.select("td").get(1).text().replaceAll("￥|,|\\u00A0","");

            // 支出金额
            var expenMoney=element.select("td").get(2).text().replaceAll("￥|,|\\u00A0","");

            // 账户余额
            var balance=element.select("td").get(3).text().replaceAll("￥|,|\\u00A0","");
            //对方名称
            var name=element.select("td").get(4).text();
            //对方账号
            var oppositeNo=element.select("td").get(5).text();
            // 摘要 描述
            var description=element.select("td").get(6).text();

            var expense = new Expense() ;
            var category  = judgeBillCategorym(description) ;
            if(StringUtils.isBlank(category)){
                category ="SHOPPING";
            }
            expense.setCardNum(accNo);
            expense.setCategory(category);
            expense.setCurrencyType("CNY");
            expense.setDescription(description);
            expense.setId(UUID.randomUUID().toString());
            expense.setNameOnOppositeCard(name);
            expense.setOppositeBank(name);
            expense.setOppositeCardNo(oppositeNo);
            expense.setOrderIndex(i++);
            expense.setPostDate(yyyy_MM_dd_HH_mm_ss_PARSER.parse(transTime));
            expense.setTransAddr("");
            expense.setTransDate(yyyy_MM_dd_HH_mm_ss_PARSER.parse(transTime));
            expense.setBalance(new BigDecimal(balance));
            expense.setAmountMoney(new BigDecimal(madeMoney.contains("--")?expenMoney:"-"+madeMoney));
            expenses.add(expense) ;
        }
    } catch ( e) {
        logger.error("中信储蓄卡流水信息页面解析异常", e);
    }
    return expenses ;
}
/**
 * 获取流水信息的url
 * @param html
 * @param accNo
 * @param beginDate
 * @param beginDate
 * @param endDate
 * @return
 */
function getParamterUrlInfo(html, accNo, beginDate, endDate) {
    var doc = Jsoup.parse(html);
    var eles = doc.select("input");
    try{
        var judFrozenSFlag = eles.get(0).val();
        var openDate = eles.get(1).val();
        var qcAmt = eles.get(2).val();
        var creditBalance = eles.get(3).val();
        var extendFlag = eles.get(4).val();
        var subAccountNo = eles.get(5).val();
        var frozenSFlag = eles.get(6).val();
        var lossFlag = eles.get(7).val();
        var balance = eles.get(8).val();
        var originalBalance = eles.get(9).val();
        var saveType = eles.get(10).val();
        var hostAccType = eles.get(11).val();
        var currencyType = eles.get(12).val();
        var accrualStartDate = eles.get(13).val();
        var savePeriod = eles.get(14).val();
        var interestRate = eles.get(15).val();
        var forzenAmt = eles.get(16).val();
        var accountNo = eles.get(17).val();
        var jurForzenAmt = eles.get(18).val();
        var accrualEDate = eles.get(19).val();
        var recordState = eles.get(20).val();

        var url = "&isubAccInfo.judFrozenSFlag=" + judFrozenSFlag + "&isubAccInfo.openDate=" + openDate
            + "&isubAccInfo.qcAmt=" + qcAmt + "&isubAccInfo.creditBalance=" + creditBalance
            + "&isubAccInfo.extendFlag=" + extendFlag + "&isubAccInfo.subAccountNo=" + subAccountNo
            + "&isubAccInfo.frozenSFlag=" + frozenSFlag + "&isubAccInfo.balance=" + balance
            + "&isubAccInfo.lossFlag=" + lossFlag + "&isubAccInfo.originalBalance=" + originalBalance
            + "&isubAccInfo.saveType=" + saveType + "&isubAccInfo.hostAccType=" + hostAccType
            + "&isubAccInfo.currencyType=" + currencyType + "&isubAccInfo.accrualStartDate=" + accrualStartDate
            + "&isubAccInfo.savePeriod=" + savePeriod + "&isubAccInfo.interestRate=" + interestRate
            + "&isubAccInfo.forzenAmt=" + forzenAmt + "&isubAccInfo.accountNo=" + accountNo
            + "&isubAccInfo.jurForzenAmt=" + jurForzenAmt + "&isubAccInfo.accrualEDate=" + accrualEDate
            + "&isubAccInfo.recordState=" + recordState + "&stdpriacno=" + accountNo + "&accountNo=" + accNo
            + "&stdessbgdt="+beginDate+"&stdesseddt="+endDate+"&stdesssbno=&CashFlag=&recordStart=" + 1
            + "&recordNum=" + 50
            + "&std400chnn=&std400dcfg=&std400pgqf=N&std400pgtk=&std400pgts=&stdudfcyno=001&opFlag=0&stkessmnam=&largeAmount=&queryType=special&targetPage=21&beginAmt=&endAmt=&recordSize="
            + 0 + "&queryDays=&startPageFlag=&pageType=2&beforePageMap=";
        context.put("openDate", openDate) ;
        return url;
    }catch (e){
        logger.info("中信借记卡 获取借卡列表失败 停止抓取")
        return "";
    }

}
/**
 * 获取之前12个月的第一天:格式:2016-12-01
 *
 * @return
 */
function getFirstMonthFirstDay() {

    var lst = new ArrayList();
    var calendar = new GregorianCalendar();
    var dfdate = new SimpleDateFormat("yyyyMMdd");
    for (var i = 0; i < 12; i++) {
        calendar.setTime(new Date());
        calendar.add(Calendar.MONTH, -1 * i);
        var gcLast = Calendar.getInstance();
        gcLast.setTime(calendar.getTime());
        gcLast.set(Calendar.DAY_OF_MONTH, 1);
        lst.add(dfdate.format(gcLast.getTime()));
    }
    return lst;
}

/**
 * 获取之前12个月的最后一天,格式:2016-12-31,本月返回今天
 *
 * @return
 */
function getBeforMonthLast() {

    var lst = new ArrayList();
    var calendar = new GregorianCalendar();
    var dfdate = new SimpleDateFormat("yyyyMMdd");
    for (var i = -1; i < 11; i++) {
        calendar.setTime(new Date());
        calendar.add(Calendar.MONTH, -1 * i);
        var gcLast =  Calendar.getInstance();
        gcLast.setTime(calendar.getTime());
        gcLast.set(Calendar.DATE, 1);
        gcLast.add(Calendar.DATE, -1);
        if (gcLast.getTime().after(new Date())) {
            lst.add(dfdate.format(new Date()));
        } else {
            lst.add(dfdate.format(gcLast.getTime()));
        }
    }
    return lst;
}

/**
 * 根据描述判断类型
 * @param description
 * @return
 */
function judgeBillCategorym(description){
    if (StringUtils.isNotBlank(description)) {
        if (description.contains("工资")) {
            return "SALARY";
        }else if (description.contains("奖金")) {
            return "BONUS";
        }else if (description.contains("利息")||description.contains("结息")) {
            return "ACCRUAL";
        }else if (description.contains("存现")) {
            return "DEPOSIT";
        }else if (description.contains("转账")) {
            return "TRANSFER";
        }else if (description.contains("借贷")) {
            return "LOANS";
        }else if (description.contains("冲账")) {
            return "REVERSE";
        }else if(description.contains("退款")){
            return "REFUND";
        }else if(description.contains("收益")){
            return "EARNINGS";
        }else if(description.contains("报销")){
            return "CLAIM";
        }else if(description.contains("取现")){
            return "WITHDRAW";
        }else if(description.contains("手续费")){
            return "HANDLINGFEE";
        }else if(description.contains("转账")){
            return "TRANSFER";
        }else if(description.contains("还贷")||description.contains("还款")){
            return "REPAYMENT";
        }else if(description.contains("理财")){
            return "FINANCE";
        }else if(description.contains("消费")||description.contains("支付")){
            return "CONSUMPTION";
        }else if(description.contains("房租")){
            return "RENT";
        }else if(description.contains("公积金")){
            return "FUND";
        }else if(description.contains("社保")){
            return "SOCIALSECURITY";
        }else if(description.contains("通讯费")){
            return "COMMUNICATIONFEE";
        }else if(description.contains("生活费")){
            return "LIVINGEXPENSE";
        }else if(description.contains("其他收入")||description.contains("S")){
            return "OTHERREVENUE";
        }else if(description.contains("其他支出")){
            return "OTHEREXPENSE";
        }else{
            return "OTHERFEE";
        }
    }else{
        return "CONSUMPTION";
    }
}